//定义栈的数据结构，请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中，调用 min、push 及 pop 的时间复杂度都是 O(1)。 
//
// 
//
// 示例: 
//
// MinStack minStack = new MinStack();
//minStack.push(-2);
//minStack.push(0);
//minStack.push(-3);
//minStack.min();   --> 返回 -3.
//minStack.pop();
//minStack.top();      --> 返回 0.
//minStack.min();   --> 返回 -2.
// 
//
// 
//
// 提示： 
//
// 
// 各函数的调用总次数不超过 20000 次 
// 
//
// 
//
// 注意：本题与主站 155 题相同：https://leetcode-cn.com/problems/min-stack/ 
// Related Topics 栈 设计 👍 337 👎 0

package leetcode.editor.offer;

import java.util.Stack;

class BaoHanMinhanShuDeZhanLcof {
    public static void main(String[] args) {
        MinStack solution = new BaoHanMinhanShuDeZhanLcof().new MinStack();
    }

    //leetcode submit region begin(Prohibit modification and deletion)
    class MinStack {

        // 数据栈 A ： 栈 A 用于存储所有元素，保证入栈 push() 函数、出栈 pop() 函数、获取栈顶 top() 函数的正常逻辑。
        Stack<Integer> stack1;
        // 辅助栈 B ： 栈 B 中存储栈 A 中所有 非严格降序 的元素，则栈 AA中的最小元素始终对应栈 B 的栈顶元素，即 min() 函数只需返回栈 BB 的栈顶元素即可。
        Stack<Integer> stack2;


        /**
         * initialize your data structure here.
         */
        public MinStack() {
            stack1 = new Stack<>();
            stack2 = new Stack<>();
        }

        public void push(int x) {
            stack1.push(x);
            if (stack2.isEmpty()) {
                stack2.push(x);   // stack2为空，那么这个元素就是最小的
            } else {    // stack2不为空
                if (stack2.peek() >= x) stack2.push(x);  // 如果前面的数大于入栈的数，那么就直接入栈
            }
        }

        public void pop() {
            // 注意使用equals，在[-128,127]会存在缓存
            if (stack1.pop().equals(stack2.peek())) stack2.pop();    // 如果stack1出栈的元素和stack2栈顶相等，那么就一起出栈
        }

        public int top() {
            return stack1.peek();
        }

        public int min() {
            return stack2.peek();
        }
    }
/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack obj = new MinStack();
 * obj.push(x);
 * obj.pop();
 * int param_3 = obj.top();
 * int param_4 = obj.min();
 */
//leetcode submit region end(Prohibit modification and deletion)

}
